home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et-2_2.lha / et2.2 / src / ObjArray.C < prev    next >
C/C++ Source or Header  |  1990-12-06  |  6KB  |  319 lines

  1. //$ObjArray,ObjArrayIter$
  2. #include "ObjArray.h"
  3. #include "Error.h"
  4. #include "Storage.h"
  5. #include "FixedStorage.h"
  6. #include "String.h"
  7.  
  8. typedef int (*COMPARE)(const void*, const void*);
  9.  
  10. #ifndef __GNUG__
  11.     extern "C" void qsort(void*, int, int, COMPARE);
  12. #endif
  13.  
  14. char *cOutOfBoundsError= "out of bounds %d size %d in 0x%x";
  15. char *cMethodName= "operator[]";
  16.  
  17. //---- class ObjArray ---------------------------------------------------------
  18.  
  19. MetaImpl(ObjArray, (T(lb), TVP(cont,size), 0));
  20.  
  21. ObjArray::ObjArray(int s, int lowerBound)                
  22.     if (s <= 0)
  23.     s= 10;
  24.     cont= new ObjPtr[size= s];
  25.     lb= lowerBound;
  26. }
  27.  
  28. ObjArray::~ObjArray()
  29. {
  30.     SafeDelete(cont);
  31. }
  32.  
  33. void ObjArray::InitNew()
  34. {
  35.     cont= new ObjPtr[cCollectionInitCap];
  36.     lb= 0;
  37. }
  38.  
  39. void ObjArray::FreeAll()
  40. {
  41.     register int i;
  42.  
  43.     for (i= 0; i < size; i++) {
  44.     if (cont[i]) {
  45.         cont[i]->FreeAll();
  46.         SafeDelete(cont[i]);
  47.     }
  48.     }
  49.     size= 0;
  50. }
  51.  
  52. ObjPtr ObjArray::RemoveAt(int i)
  53.     ObjPtr t;
  54.  
  55.     if (!BoundsOk("RemoveAt", i))
  56.     return 0;
  57.     t= cont[i-lb];
  58.     cont[i-lb]= 0; 
  59.     Changed();
  60.     return t;
  61. }
  62.  
  63. ObjPtr ObjArray::Remove(ObjPtr a)
  64. {   
  65.     register int i;
  66.     register ObjPtr op;
  67.  
  68.     for (i = 0; i < size; i++) {
  69.     op= cont[i];
  70.     if (op && op->IsEqual(a)) {
  71.         cont[i]= 0;
  72.         Changed();
  73.         return op;
  74.     }
  75.     }
  76.     return 0;
  77. }
  78.  
  79. ObjPtr ObjArray::RemovePtr(ObjPtr a)
  80. {   
  81.     register int i;
  82.     register ObjPtr op;
  83.  
  84.     for (i = 0; i < size; i++) {
  85.     op= cont[i];
  86.     if (op && op == a) {
  87.         cont[i]= 0;
  88.         Changed();
  89.         return op;
  90.     }
  91.     }
  92.     return 0;
  93. }
  94.  
  95. void ObjArray::Expand(int newSize)
  96. {
  97.     if (newSize < 0) {
  98.     Error ("Expand", "newSize < 0");
  99.     return;
  100.     }
  101.     if (newSize == size)
  102.     return;
  103.     if (newSize <= size) {
  104.     // if the array is shrinked check whether there are nonempty entries
  105.     for (int j = newSize; j < size; j++)
  106.         if (cont[j] != 0) {
  107.         Error ("Expand", "expand would cut off nonempty entries at %d", j);
  108.         return;
  109.         }
  110.     }            
  111.     cont= (ObjPtr*) Realloc(cont, newSize * sizeof(ObjPtr));
  112.     size= newSize;
  113. }
  114.  
  115. Iterator *ObjArray::MakeIterator()
  116. {
  117.     return new ObjArrayIter(this);
  118. }
  119.  
  120. ObjPtr ObjArray::AtPut(int i, ObjPtr ob)
  121.     if (!BoundsOk ("AtPut", i))
  122.     return 0;
  123.     ObjPtr t= cont[i-lb];
  124.     cont[i-lb]= ob;
  125.     Changed();
  126.     return t;
  127. }
  128.  
  129. void ObjArray::AtPutAndExpand(int i,ObjPtr op)
  130. {
  131.     if (i < lb) {
  132.     Error ("AtPutAndExpand", "out of bounds at %d in %x", i, this);
  133.     return;
  134.     }
  135.     if (i-lb >= size) 
  136.     Expand (max(i, GrowBy(size)));
  137.     cont[i-lb] = op; 
  138.     Changed();
  139. }
  140.  
  141. ObjPtr ObjArray::Add(ObjPtr op)
  142. {
  143.     register int i;
  144.  
  145.     if (cont == 0)
  146.     cont= new ObjPtr[size= 10];
  147.     for (i= 0; i < size; i++)
  148.     if (cont[i] == 0)
  149.         break;
  150.     if (i >= size)
  151.     Expand(GrowBy(size));
  152.     cont[i]= op; 
  153.     Changed();
  154.     return 0;
  155. }
  156.  
  157. int ObjArray::IndexOf (ObjPtr ob)
  158. {
  159.     register int i;
  160.  
  161.     for (i = 0; i < size; i++)
  162.     if (ob && ob->IsEqual(cont[i])) 
  163.         return i+lb;
  164.     return -1;
  165. }
  166.  
  167. int ObjArray::IndexOfPtr (ObjPtr ob)
  168. {
  169.     register int i;
  170.  
  171.     for (i= 0; i < size; i++)
  172.     if (ob == cont[i]) 
  173.         return i+lb;
  174.     return -1;
  175. }
  176.  
  177. ObjPtr ObjArray::At(int i)
  178. {
  179.     if (!BoundsOk("At", i))
  180.     return 0;
  181.     return cont[i-lb];
  182. }
  183.  
  184. int ObjArray::Compare (ObjPtr)
  185. {
  186.     MayNotUse ("Compare");
  187.     return -2;
  188. }
  189.  
  190. bool ObjArray::IsEqual (ObjPtr ob)
  191. {
  192.     if (!ob->IsKindOf(ObjArray))
  193.     return FALSE;
  194.     ObjArray *t = (ObjArray *) ob; 
  195.     if (t->size != size || t->lb != lb)
  196.     return FALSE;
  197.     for (int i= 0; i < Size(); i++) {
  198.     if (cont[i] == 0 && t->cont[i] == 0)
  199.         continue;
  200.     if (cont[i] == 0 || t->cont[i] == 0)
  201.         break;
  202.     if (!cont[i]->IsEqual(t->cont[i]))
  203.         break;
  204.     }
  205.     return i == size;
  206. }
  207.  
  208. ostream& ObjArray::PrintOn(ostream &s)
  209. {
  210.     Object::PrintOn(s); // supress Collection::PrintOn
  211.     s << Size() SP;
  212.     for (int i= 0; i < Size(); i++) 
  213.     s << cont[i] SP;
  214.     return s NL;
  215. }
  216.  
  217. istream& ObjArray::ReadFrom(istream &s)
  218. {
  219.     Object::ReadFrom(s);
  220.     delete cont;
  221.     s >> size;
  222.     cont= new ObjPtr[size];
  223.     for (int i= 0; i < size; i++)
  224.     s >> cont[i];
  225.     return s;
  226. }
  227.  
  228. unsigned long ObjArray::Hash ()
  229. {
  230.     register u_long i, hash;
  231.  
  232.     for (i= hash= size; i < size; i++)
  233.     if (cont[i])
  234.         hash ^= cont[i]->Hash();
  235.     return hash;
  236. }
  237.  
  238. static int CompareFun(ObjPtr* a, ObjPtr* b) 
  239.     if (*a == 0 || *b == 0)
  240.     return 0;
  241.     return (*a)->Compare(*b);
  242. }
  243.  
  244. void ObjArray::Sort(int upto)
  245. {
  246.     qsort(cont, min(size, upto-lb), sizeof(ObjPtr), (COMPARE)CompareFun);
  247. }
  248.  
  249. int ObjArray::BinarySearch(ObjPtr op, int upto)
  250. {
  251.     register int base, position, last, result;
  252.     register Object *op2;
  253.     
  254.     if (op == 0)
  255.     return -1;
  256.     
  257.     base= 0;
  258.     last= min(size, upto-lb) - 1;
  259.     
  260.     while (last >= base) {
  261.     position= (base+last) / 2;
  262.     op2= cont[position];
  263.     if ((op2 == 0) || (result= op->Compare(op2)) == 0)
  264.         return position + lb;
  265.     if (result < 0)
  266.         last= position-1;
  267.     else
  268.         base= position+1;
  269.     }
  270.     return -1;
  271. }
  272.  
  273. //---- class ObjArray -------------------------------------------------------
  274.  
  275. ObjArrayIter::ObjArrayIter(Collection *s)
  276. {
  277.     cs= (ObjArray*)s; ce= 0; 
  278. }
  279.  
  280. ObjArrayIter::~ObjArrayIter()
  281. {
  282. }
  283.  
  284. void *ObjArrayIter::operator new(size_t sz)
  285. {
  286.     return MemPools::Alloc(sz);
  287. }
  288.  
  289. void ObjArrayIter::operator delete(void *vp)
  290. {
  291.     MemPools::Free(vp, sizeof(ObjArrayIter)); 
  292. }
  293.  
  294. void ObjArrayIter::Reset(Collection *s)
  295. {
  296.     if (s == 0)
  297.     s= cs;
  298.     cs= (ObjArray*)s;
  299.     ce= 0;
  300. }
  301.  
  302. ObjPtr ObjArrayIter::operator()()
  303. {
  304.     for (;ce < cs->Size() && cs->cont[ce] == 0; ce++)
  305.     ;
  306.     if (ce < cs->Size())
  307.     return cs->cont[ce++];
  308.     return 0;
  309. }
  310.  
  311. bool ObjArrayIter::Filter(ObjPtr)
  312. {
  313.     return TRUE;
  314. }
  315.